package com.gitee.fsmxm.thinking.in.spring.bean.definition;

import com.gitee.fsmxm.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * bean 初始化 demo
 */
public class BeanInitializationDemo {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

        applicationContext.register(BeanInitializationDemo.class);

        applicationContext.refresh();
        System.out.println("spring应用上下文启动完毕");

        // @Lazy 在使用bean的时候才会进行初始化
        UserFactory2 userFactory2 = applicationContext.getBean(UserFactory2.class);
        System.out.println(userFactory2);

        System.out.println("准备关闭spring应用上下文");
        applicationContext.close();
        System.out.println("已经关闭spring应用上下文");

        userFactory2 = null;
        System.gc();
    }

    @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
    @Lazy(false) // 决定该bean初始化顺序（是否使用时菜初始化）
    public UserFactory2 userFactory2() {
        return new UserFactory2();
    }


    public static class UserFactory2 implements InitializingBean, DisposableBean {

        public UserFactory2() {
            System.out.println("UserFactory2 constructor ...");
        }

        public void initMethod() {
            System.out.println("initMethod ...");
        }

        @PostConstruct
        public void postConstructor() {
            System.out.println("@PostConstruct ...");
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("InitializingBean#afterPropertiesSet ...");
        }

        public User createUser() {
            User user = new User();
            user.setName("小马哥");
            user.setId(1L);
            return user;
        }

        @Override
        public void destroy() throws Exception {
            System.out.println("DisposableBean#destory ...");
        }

        @PreDestroy
        public void preDestroy() {
            System.out.println("@PreDestroy ...");
        }

        public void destroyMethod() {
            System.out.println("destroyMethod ...");
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println("finalize ...");
        }
    }

}
